/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package batailledesardennes.game.input;

import batailledesardennes.game.GameEnv;
import batailledesardennes.game.entity.task.MoveTask;
import batailledesardennes.game.env.ViewPortManager;
import batailledesardennes.game.interfaces.Controllable;
import batailledesardennes.game.entity.Entity;
import batailledesardennes.game.ui.SelectionDrawable;
import batailledesardennes.util.geomFloat.Point;
import batailledesardennes.util.geomFloat.Rectangle;
import org.newdawn.slick.Input;

/**
 *
 * @author cghislai
 */
public class InputHandler {
   private final static float vpSpeed = 0.3f;
   private SelectionDrawable selectionDrawable;
   private final GameEnv env;
   private boolean shiftDown;
   private boolean upDown;
   private boolean downDown;
   private boolean leftDown;
   private boolean rightDown;
   private boolean mouseLeftDown;
   private Point selectionAnchor;

   public InputHandler(GameEnv env) {
      this.env = env;
   }

   public void processMouseEvent(MouseEvent event) {
      if (event.getButton() == MouseEvent.Button.LEFT) {
         mouseLeftDown = event.isDown();
         processLeftMouseEvent(event);
      }
      if (event.getType() == MouseEvent.Type.MOVED && mouseLeftDown) {
         float x = env.getViewPortManager().getGameLeftX() + event.getX();
         float y = env.getViewPortManager().getGameTopY() + event.getY();
         selectionDrawable.setX((int) x);
         selectionDrawable.setY((int) y);
      }
      if (event.getButton() == MouseEvent.Button.RIGHT && event.isDown()) {
         processRightClick(event);
      }
   }

   public void setSelectionDrawable(SelectionDrawable selectionDrawable) {
      this.selectionDrawable = selectionDrawable;
   }

   public void update(int delta) {
      selectionDrawable.setActive(mouseLeftDown);
      ViewPortManager viewPort = env.getViewPortManager();
      float dist = vpSpeed * delta * (shiftDown ? 5 : 1);
      if (leftDown != rightDown) {
         float newX = viewPort.getGameLeftX() + (leftDown ? -dist : dist);
         newX = Math.max(newX, 0);
         newX = Math.min(newX, env.getMap().getWidth() - viewPort.getWidth());
         viewPort.setGameLeftX(newX);
      }
      if (upDown != downDown) {
         float newY = viewPort.getGameTopY() + (upDown ? -dist : dist);
         newY = Math.max(newY, 0);
         newY = Math.min(newY, env.getMap().getHeight() - viewPort.getHeight());
         viewPort.setGameTopY(newY);
      }
   }

   public void processKeyEvent(KeyEvent keyEvent) {
      switch (keyEvent.getKeyCode()) {
         case Input.KEY_LSHIFT:
         case Input.KEY_RSHIFT: {
            shiftDown = keyEvent.isDown();
            break;
         }
         case Input.KEY_LEFT: {
            leftDown = keyEvent.isDown();
            break;
         }
         case Input.KEY_RIGHT: {
            rightDown = keyEvent.isDown();
            break;
         }
         case Input.KEY_UP: {
            upDown = keyEvent.isDown();
            break;
         }
         case Input.KEY_DOWN: {
            downDown = keyEvent.isDown();
            break;
         }
      }
   }

   private void processLeftMouseEvent(MouseEvent event) {
      float x = env.getViewPortManager().getGameLeftX() + event.getX();
      float y = env.getViewPortManager().getGameTopY() + event.getY();
      selectionDrawable.setX((int) x);
      selectionDrawable.setY((int) y);
      switch (event.getType()) {
         case PRESSED: {
            selectionAnchor = new Point(x, y);
            selectionDrawable.setAnchorX((int) selectionAnchor.getX());
            selectionDrawable.setAnchorY((int) selectionAnchor.getY());
            break;
         }
         case RELEASED: {
            selectionAnchor = null;
            Rectangle rect = new Rectangle(selectionDrawable.getLeftX(), selectionDrawable.getTopY(), selectionDrawable.getWidth(), selectionDrawable.getHeight());
            env.getEntitiesManager().setSelection(rect);
            break;
         }
      }
   }

   private void processRightClick(MouseEvent event) {
      MoveTask moveTask = new MoveTask();
      float x = env.getViewPortManager().getGameX(event.getX());
      float y = env.getViewPortManager().getGameY(event.getY());
      moveTask.setTarget(new Point(x, y));
      for (Entity e : env.getEntitiesManager().getSelectedEntities()) {
         if (Controllable.class.isAssignableFrom(e.getClass())) {
            Controllable c = (Controllable) e;
            moveTask.setEntity(e);
            c.addTask(moveTask, shiftDown);
         }
      }
   }
}
